package com.kamistoat.meimeistore.commonredis.utils;

import org.redisson.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * redisson工具类
 */
@SuppressWarnings(value = {"unchecked", "rawtypes"})
@Component
public class RedissonUtils {

    //    private static final RedissonClient CLIENT = SpringUtils.getBean(RedissonClient.class);
    @Autowired
    RedissonClient redissonClient;

    public RedissonClient getRedissonClient(){
        return redissonClient;
    }


    /**
     * 使用redisson向redis中添加一个普通的k-v，永不过期
     *
     * @param key 目标在redis中的完整key。之后所有的方法中传入的key都是包含前缀的完整key
     * @param value
     * @param <T>
     */
    public <T> void setCacheObject(final String key, final T value) {
        setCacheObject(key, value, false);
    }

    /**
     * 使用redisson向redis中添加一个普通的k-v
     *
     * @param key
     * @param value
     * @param isSaveTtl 是否保留TTL有效期(例如: set之前ttl剩余90 set之后还是为90)
     * @param <T>
     */
    public <T> void setCacheObject(final String key, final T value, final boolean isSaveTtl) {
        RBucket<T> bucket = redissonClient.getBucket(key);
        if (isSaveTtl) {
            // 保留原本的过期时间.则先获取原本的过期时间(单位毫秒)
            long timeToLive = bucket.remainTimeToLive();
            bucket.set(value, timeToLive, TimeUnit.MILLISECONDS);
        }else{
            // 否则永不过期
            bucket.set(value);
        }
    }

    /**
     * 使用redisson向redis中添加一个普通的k-v，并携带过期时间
     * @param key
     * @param value
     * @param timeToLive
     * @param timeUnit
     * @param <T>
     */
    public <T> void setCacheObject(final String key, final T value, final long timeToLive, final TimeUnit timeUnit) {
        RBucket<T> bucket = redissonClient.getBucket(key);
        bucket.set(value, timeToLive, timeUnit);
    }

    /**
     * 使用redisson从redis中获取普通的k-v
     * @param key
     * @param <T>
     * @return
     */
    public <T> T getCacheObject(final String key) {
        RBucket<T> rBucket = redissonClient.getBucket(key);
        return rBucket.get();
    }

    /**
     * 使用redisson从redis中删除指定的对象
     * @param key
     * @return
     */
    public boolean deleteObject(final String key){
        return redissonClient.getBucket(key).delete();
    }

    /**
     * 使用redisson从redis中删除多个对象
     * @param collection 多个对象需要使用集合的形式给出
     */
    public void deleteObject(final Collection collection){
        // 创建redisson批量操作对象
        RBatch batch = redissonClient.createBatch();
        // 为批量操作添加任务
        collection.forEach(coll -> {
            batch.getBucket(coll.toString()).deleteAsync();
        });
        batch.execute();
    }


    /**
     * 使用redisson从redis中获取与 pattern 匹配的所有key
     * @param pattern 匹配式
     * @return 满足Collection接口的类即可。一般就是 List
     */
    public Collection<String> keys(final String pattern){
        Stream<String> keysStream = redissonClient.getKeys().getKeysStreamByPattern(pattern);
        return keysStream.collect(Collectors.toList());
    }
}
